package com.yc.happ.web.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.gson.Gson;

public abstract class BaseServlet extends HttpServlet {

	/**
	 * 
	 */
	private static final long serialVersionUID = -7006328652251605520L;
	//debug
	//f5进入方法中执行
	//f6单步执行
	//f7跳出方法
	protected String getRequestFlag(HttpServletRequest request) {
		String requestURI = request.getRequestURI();
		int start = requestURI.lastIndexOf("/") + 1;
		return requestURI.substring(start);
	}
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doPost(req,resp);
	}
	protected void responseOut(HttpServletResponse response, String jsonStr)
			throws IOException {
		PrintWriter out = response.getWriter();
		out.println(jsonStr);
		out.flush();
		out.close();
	}
	
	protected String toJson(Object obj) {
		Gson g = new Gson();
		return g.toJson(obj);
	}
/*	*//**
	 * 
	 * @param request  请求处理对象
	 * @param clazz  要转换成的实体对象的类对象
	 * @return  实体对象
	 *//*
	protected <T> T getReqParamObj(HttpServletRequest request, Class<T> clazz) {
		T t = null;
		try {
			t = clazz.newInstance();  //通过类对象，创建类的对象相当(new T();)
			Field[] fs = clazz.getDeclaredFields(); // 取到指定类对象的类的属性
			for (Field f : fs) {
				String fn = f.getName(); // 取到属性名
				String param = request.getParameter(fn); // 通过属性名取到请求数据值
				if (param != null) {
					String mn = "set" + fn.substring(0, 1).toUpperCase()
							+ fn.substring(1); // 对应属性的set方法名
					Method m = clazz.getDeclaredMethod(mn, f.getType()); // 对应属性的set方法的对象
					if(f.getType().getName().equals(Integer.class.getName())){
						 m.invoke(t, Integer.valueOf(param));
					}
					else if(f.getType().getName().equals(Double.class.getName())){
						 m.invoke(t, Double.valueOf(param));
					}
					else if(f.getType().getName().equals(Date.class.getName())){
						SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
						 m.invoke(t, sdf.parse(param));
					}else{
						m.invoke(t, param);
					}
				}
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		} 
		return t;
	}*/
	/**
	 * 在建名前加入set
	 * @param map
	 * @return
	 */
	private Map<String,String[]> pareseRequest(Map<String,String[]> map){
		Map<String,String[]> newmap=new HashMap<String,String[]>();
		for(Map.Entry<String, String[]> entry:map.entrySet()){
			String key=entry.getKey();
			key="set" +key.substring(0,1).toUpperCase()+key.substring(1);
			String[] value=entry.getValue();
			newmap.put(key, value);
		}
		return map;
	}
	/**
	 * 
	 * @param request  请求处理对象
	 * @param clazz  要转换成的实体对象的类对象
	 * @return  实体对象
	 */
	protected <T> T getReqParamObj(HttpServletRequest request, Class<T> clazz) {
		T t = null;
		Map<String,String[]> map=request.getParameterMap();//取出所有的request中的参数
		
		try {
			t = clazz.newInstance();  //通过类对象，创建类的对象相当(new T();)
			Method[] ms=clazz.getMethods();
			for(Method m:ms){
				String MethodName=m.getName();//取出每个方法的名字
				for(Map.Entry<String, String[]> entry:map.entrySet()){
					String key=entry.getKey();
					String[] values=entry.getValue();
					if(key.equals(MethodName)){
						Class parameterType=m.getParameterTypes()[0];
						if(parameterType.getName().startsWith("[")){
							//数组
							extractArrayParameterValue(t, m, values, parameterType);
						}else{
							//单个
							extractSingleParameterValue(t, m, values, parameterType);
						}
			
					}
				}
				
			}
			Field[] fs = clazz.getDeclaredFields(); // 取到指定类对象的类的属性
			for (Field f : fs) {
				String fn = f.getName(); // 取到属性名
				String param = request.getParameter(fn); // 通过属性名取到请求数据值
				if (param != null) {
					String mn = "set" + fn.substring(0, 1).toUpperCase()
							+ fn.substring(1); // 对应属性的set方法名
					Method m = clazz.getDeclaredMethod(mn, f.getType()); // 对应属性的set方法的对象
					if(f.getType().getName().equals(Integer.class.getName())){
						 m.invoke(t, Integer.valueOf(param));
					}
					else if(f.getType().getName().equals(Double.class.getName())){
						 m.invoke(t, Double.valueOf(param));
					}
					else if(f.getType().getName().equals(Date.class.getName())){
						SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
						 m.invoke(t, sdf.parse(param));
					}else{
						m.invoke(t, param);
					}
				}
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		} 
		return t;
	}
	/**
	 * 传递单个数据
	 * @param t
	 * @param m
	 * @param values
	 * @param parameterType
	 * @throws NumberFormatException
	 * @throws IllegalAccessException
	 * @throws IllegalArgumentException
	 * @throws InvocationTargetException
	 * @throws ParseException
	 */
	private <T> void extractSingleParameterValue(T t,Method m,String[] values,Class parameterType) throws NumberFormatException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, ParseException{
		String s=values[0];
		String paramesTypeName=parameterType.getName();
		if("int".equals(paramesTypeName)||"java.lang.Integer".equals(paramesTypeName)){
			m.invoke(t, Integer.parseInt(s));
		}else if("double".equals(paramesTypeName)||"java.lang.Double".equals(paramesTypeName)){
			m.invoke(t, Double.parseDouble(s));
		}else if("float".equals(paramesTypeName)||"java.lang.Float".equals(paramesTypeName)){
			m.invoke(t, Float.parseFloat(s));
		}else if("byte".equals(paramesTypeName)||"java.lang.Byte".equals(paramesTypeName)){
			m.invoke(t, Byte.parseByte(s));
		}else if("Date".equals(paramesTypeName)){
			SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm");
			m.invoke(t,sdf.parse(s));
		}else{
			m.invoke(t,s);
		}
	}
	/**
	 * 得到所有的数组
	 * @param t
	 * @param m
	 * @param values
	 * @param parameterType
	 * @throws NumberFormatException
	 * @throws IllegalAccessException
	 * @throws IllegalArgumentException
	 * @throws InvocationTargetException
	 * @throws ParseException
	 */
	private <T> void extractArrayParameterValue(T t,Method m,String[] values,Class parameterType) throws NumberFormatException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, ParseException{
		String parameterTypeName=parameterType.getName();
		if("[I".equals(parameterTypeName)){
			int[] intarray=new int[values.length];
			for(int i=0;i<intarray.length;i++){
				intarray[i]=Integer.parseInt(values[i]);
			}
			m.invoke(t,intarray);
		}else if("[Ljava.lang.Integer;".equals(parameterTypeName)){
			Integer[] intarray=new Integer[values.length];
			for(int i=0;i<intarray.length;i++){
				intarray[i]=Integer.parseInt(values[i]);
			}
			m.invoke(t,(Object)values);
		}else if("[D".equals(parameterTypeName)){
			double[] intarray=new double[values.length];
			for(int i=0;i<intarray.length;i++){
				intarray[i]=Double.parseDouble(values[i]);
			}
			m.invoke(t,intarray);
		}else if("[Ljava.lang.Double;".equals(parameterTypeName)){
			Double[] intarray=new Double[values.length];
			for(int i=0;i<intarray.length;i++){
				intarray[i]=Double.parseDouble(values[i]);
			}
			m.invoke(t,(Object)values);
		}
		else if("[F".equals(parameterTypeName)){
			float[] intarray=new float[values.length];
			for(int i=0;i<intarray.length;i++){
				intarray[i]=Float.parseFloat(values[i]);
			}
			m.invoke(t,intarray);
		}else if("[Ljava.lang.Float;".equals(parameterTypeName)){
			Float[] intarray=new Float[values.length];
			for(int i=0;i<intarray.length;i++){
				intarray[i]=Float.parseFloat(values[i]);
			}
			m.invoke(t,(Object)values);
		}else if("[B".equals(parameterTypeName)){
			byte[] intarray=new byte[values.length];
			for(int i=0;i<intarray.length;i++){
				intarray[i]=Byte.parseByte(values[i]);
			}
			m.invoke(t,intarray);
		}else if("[Ljava.lang.Byte;".equals(parameterTypeName)){
			Byte[] intarray=new Byte[values.length];
			for(int i=0;i<intarray.length;i++){
				intarray[i]=Byte.parseByte(values[i]);
			}
			m.invoke(t,(Object)values);
		}else{
			m.invoke(t,(Object)values);
		}
	}
}
